package org.distributed.transaction.core.process;

import java.lang.reflect.Method;

import org.distributed.transaction.core.adapter.TransactionProcessorAdapter;
import org.distributed.transaction.core.context.TccTransactionInfo;
import org.distributed.transaction.core.context.TransactionContext;
import org.distributed.transaction.core.context.TransactionStatus;
import org.distributed.transaction.core.exception.TransactionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class TccStartTransactionProcessor implements TransactionProcessor {

	@Autowired
	private TransactionProcessorAdapter transactionProcessorAdapter;

	@Override
	public void preBusinessCode(TransactionContext transactionContext) throws TransactionException {
		transactionProcessorAdapter.createGroup(transactionContext);
	}

	@Override
	public void onBusinessCodeError(TransactionContext transactionContext, Throwable throwable)
			throws TransactionException {
		transactionContext.setTransactionStatus(TransactionStatus.CANCELLING);
	}

	@Override
	public void onBusinessCodeSuccess(TransactionContext transactionContext, Object result)
			throws TransactionException {
		transactionContext.setTransactionStatus(TransactionStatus.CONFIRMING);
	}

	@Override
	public void clear(TransactionContext transactionContext) {
		transactionProcessorAdapter.notifyGroup(transactionContext);

		TccTransactionInfo tccTransactionInfo = (TccTransactionInfo) transactionContext.getTransactionInfo();
		// Tcc 事务 提交/回滚 执行类
		Object executeClass = tccTransactionInfo.getExecuteClass();

		try {
			// 事务事务状态选择confirm和cancel
			Method executeMethod;
			if (TransactionStatus.CONFIRMING.equals(transactionContext.getTransactionStatus())) {
				executeMethod = executeClass.getClass().getMethod(tccTransactionInfo.getConfirmMethod(),
						tccTransactionInfo.getMethodTypeParameter());
			} else {
				executeMethod = executeClass.getClass().getMethod(tccTransactionInfo.getCancelMethod(),
						tccTransactionInfo.getMethodTypeParameter());
			}
			try {
				// 执行confirm或者cancel
				executeMethod.invoke(executeClass, tccTransactionInfo.getMethodParameter());
			} catch (Exception e) {
				e.printStackTrace();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}
